#include "dominion.h"
#include "dominion_helpers.h"
#include "rngs.h"
#include <stdio.h>
#include <math.h>
#include <stdlib.h>

int compare(const void* a, const void* b) {
  if (*(int*)a > *(int*)b)
    return 1;
  if (*(int*)a < *(int*)b)
    return -1;
  return 0;
}

struct gameState* newGame() {
  struct gameState* g = malloc(sizeof(struct gameState));
  return g;
}

int* kingdomCards(int k1, int k2, int k3, int k4, int k5, int k6, int k7,
		  int k8, int k9, int k10) {
  int* k = malloc(10 * sizeof(int));
  k[0] = k1;
  k[1] = k2;
  k[2] = k3;
  k[3] = k4;
  k[4] = k5;
  k[5] = k6;
  k[6] = k7;
  k[7] = k8;
  k[8] = k9;
  k[9] = k10;
  return k;
}

int initializeGame(int numPlayers, int kingdomCards[10], int randomSeed,
		   struct gameState *state) {

  int i;
  int j;
  int it;			
  //set up random number generator
  SelectStream(1);
  PutSeed((long)randomSeed);
  
  //check number of players
  if (numPlayers > MAX_PLAYERS || numPlayers < 2)
    {
      return -1;
    }

  //set number of players
  state->numPlayers = numPlayers;

  //check selected kingdom cards are different
  for (i = 0; i < 10; i++)
    {
      for (j = 0; j < 10; j++)
        {
	  if (j != i && kingdomCards[j] == kingdomCards[i])
	    {
	      return -1;
	    }
        }
    }


  //initialize supply
  ///////////////////////////////

  //set number of Curse cards
  if (numPlayers == 2)
    {
      state->supplyCount[curse] = 10;
    }
  else if (numPlayers == 3)
    {
      state->supplyCount[curse] = 20;
    }
  else
    {
      state->supplyCount[curse] = 30;
    }

  //set number of Victory cards
  if (numPlayers == 2)
    {
      state->supplyCount[estate] = 8;
      state->supplyCount[duchy] = 8;
      state->supplyCount[province] = 8;
    }
  else
    {
      state->supplyCount[estate] = 12;
      state->supplyCount[duchy] = 12;
      state->supplyCount[province] = 12;
    }

  //set number of Treasure cards
  state->supplyCount[copper] = 60 - (7 * numPlayers);
  state->supplyCount[silver] = 40;
  state->supplyCount[gold] = 30;

  //set number of Kingdom cards
  for (i = adventurer; i <= treasure_map; i++)       	//loop all cards
    {
      for (j = 0; j < 10; j++)           		//loop chosen cards
	{
	  if (kingdomCards[j] == i)
	    {
	      //check if card is a 'Victory' Kingdom card
	      if (kingdomCards[j] == great_hall || kingdomCards[j] == gardens)
		{
		  if (numPlayers == 2){ 
		    state->supplyCount[i] = 8; 
		  }
		  else{ state->supplyCount[i] = 12; }
		}
	      else
		{
		  state->supplyCount[i] = 10;
		}
	      break;
	    }
	  else    //card is not in the set choosen for the game
	    {
	      state->supplyCount[i] = -1;
	    }
	}

    }

  ////////////////////////
  //supply intilization complete

  //set player decks
  for (i = 0; i < numPlayers; i++)
    {
      state->deckCount[i] = 0;
      for (j = 0; j < 3; j++)
	{
	  state->deck[i][j] = estate;
	  state->deckCount[i]++;
	}
      for (j = 3; j < 10; j++)
	{
	  state->deck[i][j] = copper;
	  state->deckCount[i]++;		
	}
    }

  //shuffle player decks
  for (i = 0; i < numPlayers; i++)
    {
      if ( shuffle(i, state) < 0 )
	{
	  return -1;
	}
    }

  //draw player hands
  for (i = 0; i < numPlayers; i++)
    {  
      //initialize hand size to zero
      state->handCount[i] = 0;
      state->discardCount[i] = 0;
      //draw 5 cards
      // for (j = 0; j < 5; j++)
      //	{
      //	  drawCard(i, state);
      //	}
    }
  
  //set embargo tokens to 0 for all supply piles
  for (i = 0; i <= treasure_map; i++)
    {
      state->embargoTokens[i] = 0;
    }

  //initialize first player's turn
  state->outpostPlayed = 0;
  state->phase = 0;
  state->numActions = 1;
  state->numBuys = 1;
  state->playedCardCount = 0;
  state->whoseTurn = 0;
  state->handCount[state->whoseTurn] = 0;
  //int it; move to top

  //Moved draw cards to here, only drawing at the start of a turn
  for (it = 0; it < 5; it++){
    drawCard(state->whoseTurn, state);
  }

  updateCoins(state->whoseTurn, state, 0);

  return 0;
}

int shuffle(int player, struct gameState *state) {
 

  int newDeck[MAX_DECK];
  int newDeckPos = 0;
  int card;
  int i;

  if (state->deckCount[player] < 1)
    return -1;
  qsort ((void*)(state->deck[player]), state->deckCount[player], sizeof(int), compare); 
  /* SORT CARDS IN DECK TO ENSURE DETERMINISM! */

  while (state->deckCount[player] > 0) {
    card = floor(Random() * state->deckCount[player]);
    newDeck[newDeckPos] = state->deck[player][card];
    newDeckPos++;
    for (i = card; i < state->deckCount[player]-1; i++) {
      state->deck[player][i] = state->deck[player][i+1];
    }
    state->deckCount[player]--;
  }
  for (i = 0; i < newDeckPos; i++) {
    state->deck[player][i] = newDeck[i];
    state->deckCount[player]++;
  }

  return 0;
}

int playCard(int handPos, int choice1, int choice2, int choice3, struct gameState *state) 
{	
  int card;
  int coin_bonus = 0; 		//tracks coins gain from actions

  //check if it is the right phase
  if (state->phase != 0)
    {
      return -1;
    }
	
  //check if player has enough actions
  if ( state->numActions < 1 )
    {
      return -1;
    }
	
  //get card played
  card = handCard(handPos, state);
	
  //check if selected card is an action
  if ( card < adventurer || card > treasure_map )
    {
      return -1;
    }
	
  //play card
  if ( cardEffect(card, choice1, choice2, choice3, state, handPos, &coin_bonus) < 0 )
    {
      return -1;
    }
	
  //reduce number of actions
  state->numActions--;

  //update coins (Treasure cards may be added with card draws)
  updateCoins(state->whoseTurn, state, coin_bonus);
	
  return 0;
}

int buyCard(int supplyPos, struct gameState *state) {
  int who;
  if (DEBUG){
    printf("Entering buyCard...\n");
  }

  // I don't know what to do about the phase thing.

  who = state->whoseTurn;

  if (state->numBuys < 1){
    if (DEBUG)
      printf("You do not have any buys left\n");
    return -1;
  } else if (supplyCount(supplyPos, state) <1){
    if (DEBUG)
      printf("There are not any of that type of card left\n");
    return -1;
  } else if (state->coins < getCost(supplyPos)){
    if (DEBUG) 
      printf("You do not have enough money to buy that. You have %d coins.\n", state->coins);
    return -1;
  } else {
    state->phase=1;
    //state->supplyCount[supplyPos]--;
    gainCard(supplyPos, state, 0, who); //card goes in discard, this might be wrong.. (2 means goes into hand, 0 goes into discard)
  
    state->coins = (state->coins) - (getCost(supplyPos));
    state->numBuys--;
    if (DEBUG)
      printf("You bought card number %d for %d coins. You now have %d buys and %d coins.\n", supplyPos, getCost(supplyPos), state->numBuys, state->coins);
  }

  //state->discard[who][state->discardCount[who]] = supplyPos;
  //state->discardCount[who]++;
    
  return 0;
}

int numHandCards(struct gameState *state) {
  return state->handCount[ whoseTurn(state) ];
}

int handCard(int handPos, struct gameState *state) {
  int currentPlayer = whoseTurn(state);
  return state->hand[currentPlayer][handPos];
}

int supplyCount(int card, struct gameState *state) {
  return state->supplyCount[card];
}

int fullDeckCount(int player, int card, struct gameState *state) {
  int i;
  int count = 0;

  for (i = 0; i < state->deckCount[player]; i++)
    {
      if (state->deck[player][i] == card) count++;
    }

  for (i = 0; i < state->handCount[player]; i++)
    {
      if (state->hand[player][i] == card) count++;
    }

  for (i = 0; i < state->discardCount[player]; i++)
    {
      if (state->discard[player][i] == card) count++;
    }

  return count;
}

int whoseTurn(struct gameState *state) {
  return state->whoseTurn;
}

int endTurn(struct gameState *state) {
  int k;
  int i;
  int currentPlayer = whoseTurn(state);
  
  //Discard hand
  for (i = 0; i < state->handCount[currentPlayer]; i++){
    state->discard[currentPlayer][state->discardCount[currentPlayer]++] = state->hand[currentPlayer][i];//Discard
    state->hand[currentPlayer][i] = -1;//Set card to -1
  }
  state->handCount[currentPlayer] = 0;//Reset hand count
    
  //Code for determining the player
  if (currentPlayer < (state->numPlayers - 1)){ 
    state->whoseTurn = currentPlayer + 1;//Still safe to increment
  }
  else{
    state->whoseTurn = 0;//Max player has been reached, loop back around to player 1
  }

  state->outpostPlayed = 0;
  state->phase = 0;
  state->numActions = 1;
  state->coins = 0;
  state->numBuys = 1;
  state->playedCardCount = 0;
  state->handCount[state->whoseTurn] = 0;

  //int k; move to top
  //Next player draws hand
  for (k = 0; k < 5; k++){
    drawCard(state->whoseTurn, state);//Draw a card
  }

  //Update money
  updateCoins(state->whoseTurn, state , 0);

  return 0;
}

int isGameOver(struct gameState *state) {
  int i;
  int j;
	
  //if stack of Province cards is empty, the game ends
  if (state->supplyCount[province] == 0)
    {
      return 1;
    }

  //if three supply pile are at 0, the game ends
  j = 0;
  for (i = 0; i < 25; i++)
    {
      if (state->supplyCount[i] == 0)
	{
	  j++;
	}
    }
  if ( j >= 3)
    {
      return 1;
    }

  return 0;
}

int scoreFor (int player, struct gameState *state) {

  int i;
  int score = 0;
  //score from hand
  for (i = 0; i < state->handCount[player]; i++)
    {
      if (state->hand[player][i] == curse) { score = score - 1; };
      if (state->hand[player][i] == estate) { score = score + 1; };
      if (state->hand[player][i] == duchy) { score = score + 3; };
      if (state->hand[player][i] == province) { score = score + 6; };
      if (state->hand[player][i] == great_hall) { score = score + 1; };
      if (state->hand[player][i] == gardens) { score = score + ( fullDeckCount(player, 0, state) / 10 ); };
    }

  //score from discard
  for (i = 0; i < state->discardCount[player]; i++)
    {
      if (state->discard[player][i] == curse) { score = score - 1; };
      if (state->discard[player][i] == estate) { score = score + 1; };
      if (state->discard[player][i] == duchy) { score = score + 3; };
      if (state->discard[player][i] == province) { score = score + 6; };
      if (state->discard[player][i] == great_hall) { score = score + 1; };
      if (state->discard[player][i] == gardens) { score = score + ( fullDeckCount(player, 0, state) / 10 ); };
    }

  //score from deck
  for (i = 0; i < state->discardCount[player]; i++)
    {
      if (state->deck[player][i] == curse) { score = score - 1; };
      if (state->deck[player][i] == estate) { score = score + 1; };
      if (state->deck[player][i] == duchy) { score = score + 3; };
      if (state->deck[player][i] == province) { score = score + 6; };
      if (state->deck[player][i] == great_hall) { score = score + 1; };
      if (state->deck[player][i] == gardens) { score = score + ( fullDeckCount(player, 0, state) / 10 ); };
    }

  return score;
}

int getWinners(int players[MAX_PLAYERS], struct gameState *state) {
  int i;	
  int j;
  int highScore;
  int currentPlayer;

  //get score for each player
  for (i = 0; i < MAX_PLAYERS; i++)
    {
      //set unused player scores to -9999
      if (i >= state->numPlayers)
	{
	  players[i] = -9999;
	}
      else
	{
	  players[i] = scoreFor (i, state);
	}
    }

  //find highest score
  j = 0;
  for (i = 0; i < MAX_PLAYERS; i++)
    {
      if (players[i] > players[j])
	{
	  j = i;
	}
    }
  highScore = players[j];

  //add 1 to players who had less turns
  currentPlayer = whoseTurn(state);
  for (i = 0; i < MAX_PLAYERS; i++)
    {
      if ( players[i] == highScore && i > currentPlayer )
	{
	  players[i]++;
	}
    }

  //find new highest score
  j = 0;
  for (i = 0; i < MAX_PLAYERS; i++)
    {
      if ( players[i] > players[j] )
	{
	  j = i;
	}
    }
  highScore = players[j];

  //set winners in array to 1 and rest to 0
  for (i = 0; i < MAX_PLAYERS; i++)
    {
      if ( players[i] == highScore )
	{
	  players[i] = 1;
	}
      else
	{
	  players[i] = 0;
	}
    }

  return 0;
}

int drawCard(int player, struct gameState *state)
{	int count;
  int deckCounter;
  if (state->deckCount[player] <= 0){//Deck is empty
    
    //Step 1 Shuffle the discard pile back into a deck
    int i;
    //Move discard to deck
    for (i = 0; i < state->discardCount[player];i++){
      state->deck[player][i] = state->discard[player][i];
      state->discard[player][i] = -1;
    }

    state->deckCount[player] = state->discardCount[player];
    state->discardCount[player] = 0;//Reset discard

    //Shufffle the deck
    shuffle(player, state);//Shuffle the deck up and make it so that we can draw
   
    if (DEBUG){//Debug statements
      printf("Deck count now: %d\n", state->deckCount[player]);
    }
    
    state->discardCount[player] = 0;

    //Step 2 Draw Card
    count = state->handCount[player];//Get current player's hand count
    
    if (DEBUG){//Debug statements
      printf("Current hand count: %d\n", count);
    }
    
    deckCounter = state->deckCount[player];//Create a holder for the deck count

    if (deckCounter == 0)
      return -1;

    state->hand[player][count] = state->deck[player][deckCounter - 1];//Add card to hand
    state->deckCount[player]--;
    state->handCount[player]++;//Increment hand count
  }

  else{
    int count = state->handCount[player];//Get current hand count for player
    int deckCounter;
    if (DEBUG){//Debug statements
      printf("Current hand count: %d\n", count);
    }

    deckCounter = state->deckCount[player];//Create holder for the deck count
    state->hand[player][count] = state->deck[player][deckCounter - 1];//Add card to the hand
    state->deckCount[player]--;
    state->handCount[player]++;//Increment hand count
  }

  return 0;
}

int getCost(int cardNumber)
{
  switch( cardNumber ) 
    {
    case curse:
      return 0;
    case estate:
      return 2;
    case duchy:
      return 5;
    case province:
      return 8;
    case copper:
      return 0;
    case silver:
      return 3;
    case gold:
      return 6;
    case adventurer:
      return 6;
    case council_room:
      return 5;
    case feast:
      return 4;
    case gardens:
      return 4;
    case mine:
      return 5;
    case remodel:
      return 4;
    case smithy:
      return 4;
    case village:
      return 3;
    case baron:
      return 4;
    case great_hall:
      return 3;
    case minion:
      return 5;
    case steward:
      return 3;
    case tribute:
      return 5;
    case ambassador:
      return 3;
    case cutpurse:
      return 4;
    case embargo: 
      return 2;
    case outpost:
      return 5;
    case salvager:
      return 4;
    case sea_hag:
      return 4;
    case treasure_map:
      return 4;
    }
	
  return -1;
}

/*refactored card functions */

int adventurer_card(struct gameState *state, int currentPlayer, int temphand[])
{
    int drawntreasure = 0;
    int cardDrawn;
    int z = 0;// this is the counter for the temp hand
	
    while(drawntreasure<2){
		if (state->deckCount[currentPlayer] <1){//if the deck is empty we need to shuffle discard and add to deck
		  shuffle(currentPlayer, state);
		}
		drawCard(currentPlayer, state);
		cardDrawn = state->hand[currentPlayer][state->handCount[currentPlayer]-1];//top card of hand is most recently drawn card.
		if (cardDrawn == copper || cardDrawn == silver || cardDrawn == gold)
		  drawntreasure++;
		else{
		  temphand[z]=cardDrawn;
		  state->handCount[currentPlayer]--; //this should just remove the top card (the most recently drawn one).
		  z++;
		}
    }
    while(z-1>=0){
		state->discard[currentPlayer][state->discardCount[currentPlayer]++]=temphand[z-1]; // discard all cards in play that have been drawn
		z=z-1;
    }
    return 0;
}

int council_room_card(struct gameState *state, int currentPlayer,  int handPos)
{
	//+4 Cards
	
	int i;
	
    for (i = 0; i < 4; i++)
	{
 	   drawCard(currentPlayer, state);
	}
		
    //+1 Buy
    state->numBuys++;
		
    //Each other player draws a card
    for (i = 0; i < state->numPlayers; i++)
	{
  	  if ( i != currentPlayer )
    	{
      	  drawCard(i, state);
    	}
	}
		
    //put played card in played card pile
    discardCard(handPos, currentPlayer, state, 0);
		
    return 0;
	
}

int feast_card(struct gameState *state, int currentPlayer, int choice1, int temphand[])
{
	//gain card with cost up to 5
	
	int i = 0;
	int x = 0;
	
    //Backup hand
    for (i = 0; i <= state->handCount[currentPlayer]; i++){
			temphand[i] = state->hand[currentPlayer][i];//Backup card
			state->hand[currentPlayer][i] = -1;//Set to nothing
    }

    //Update Coins for Buy
    updateCoins(currentPlayer, state, 5);
    while( x == 1) {//Buy one card
		if (supplyCount(choice1, state) <= 0){
  		  if (DEBUG)
    		  printf("None of that card left, sorry!\n");

  			if (DEBUG){
    			printf("Cards Left: %d\n", supplyCount(choice1, state));
  		  	}
		}
		else if (state->coins < getCost(choice1)){
  		  	printf("That card is too expensive!\n");

  			if (DEBUG){
    			printf("Coins: %d < %d\n", state->coins, getCost(choice1));
  	  		}
		}
		else{

  		  	if (DEBUG){
    		  printf("Deck Count: %d\n", state->handCount[currentPlayer] + state->deckCount[currentPlayer] + state->discardCount[currentPlayer]);
  			}

  		  	gainCard(choice1, state, 0, currentPlayer);//Gain the card

  		  	if (DEBUG){
    		  printf("Deck Count: %d\n", state->handCount[currentPlayer] + state->deckCount[currentPlayer] + state->discardCount[currentPlayer]);
  			}

		}
    }     

    //Reset Hand
    for (i = 0; i <= state->handCount[currentPlayer]; i++){
		state->hand[currentPlayer][i] = temphand[i];
		temphand[i] = -1;
    }
    			
    return 0;
}

int gardens_card()
{
	return -1;
}

int mine_card(struct gameState *state, int currentPlayer, int choice1, int choice2, int handPos)
{
	int i = 0;
	int j = 0;
	
    j = state->hand[currentPlayer][choice1];  //store card we will trash

    if (state->hand[currentPlayer][choice1] < copper || state->hand[currentPlayer][choice1] > gold)
	{
  	  return -1;
	}
	
    if (choice2 > treasure_map || choice2 < curse)
	{
  	  return -1;
	}

    if ( (getCost(state->hand[currentPlayer][choice1]) + 3) > getCost(choice2) )
	{
  	  return -1;
	}

    gainCard(choice2, state, 2, currentPlayer);

    //discard card from hand
    discardCard(handPos, currentPlayer, state, 0);

    //discard trashed card
    for (j = 0; j < state->handCount[currentPlayer]; j++)
	{
  	  	if (state->hand[currentPlayer][j] == i)
    	{
      	  discardCard(j, currentPlayer, state, 0);			
     	 break;
    	}
	}
		
    return 0;
}

int remodel_card(struct gameState *state, int currentPlayer, int choice1, int choice2, int handPos)
{
	int i;
	int j;
	
    j = state->hand[currentPlayer][choice1];  //store card we will trash

    if ( (getCost(state->hand[currentPlayer][choice1]) + 2) > getCost(choice2) )
	{
  	  return -1;
	}

    gainCard(choice2, state, 0, currentPlayer);

    //discard card from hand
    discardCard(handPos, currentPlayer, state, 0);

    //discard trashed card
    for (i = 0; i < state->handCount[currentPlayer]; i++)
	{
  	  	if (state->hand[currentPlayer][i] == j)
    	{
      	  discardCard(i, currentPlayer, state, 0);			
      	break;
    	}
	}

    return 0;
}

int smithy_card(struct gameState *state, int currentPlayer, int handPos)
{
	int i;
	
    //+3 Cards
    for (i = 0; i < 3; i++)
	{
  	  drawCard(currentPlayer, state);
	}
		
    //discard card from hand
    discardCard(handPos, currentPlayer, state, 0);
    return 0;

}

int village_card(struct gameState *state, int currentPlayer, int handPos)
{
    //+1 Card
    drawCard(currentPlayer, state);
	
    //+2 Actions
    state->numActions = state->numActions + 2;
	
    //discard played card from hand
    discardCard(handPos, currentPlayer, state, 0);
    return 0;
}

int baron_card(struct gameState *state, int currentPlayer, int handPos, int choice1)
{
    state->numBuys++;//Increase buys by 1!
    if (choice1 > 0){//Boolean true or going to discard an estate
		int p = 0;//Iterator for hand!
		int card_not_discarded = 1;//Flag for discard set!
		while(card_not_discarded){
			if (state->hand[currentPlayer][p] == estate){//Found an estate card!
				state->coins += 4;//Add 4 coins to the amount of coins
				state->discard[currentPlayer][state->discardCount[currentPlayer]] = state->hand[currentPlayer][p];
				state->discardCount[currentPlayer]++;
				for (;p < state->handCount[currentPlayer]; p++){
					state->hand[currentPlayer][p] = state->hand[currentPlayer][p+1];
				}
				state->hand[currentPlayer][state->handCount[currentPlayer]] = -1;
				state->handCount[currentPlayer]--;
				card_not_discarded = 0;//Exit the loop
			}
			else if (p > state->handCount[currentPlayer]){
				if(DEBUG) {
					printf("No estate cards in your hand, invalid choice\n");
					printf("Must gain an estate if there are any\n");
				}
				if (supplyCount(estate, state) > 0){
					gainCard(estate, state, 0, currentPlayer);
					state->supplyCount[estate]--;//Decrement estates
					if (supplyCount(estate, state) == 0){
						isGameOver(state);
					}
				}
				card_not_discarded = 0;//Exit the loop
			}
		    
			else{
				p++;//Next card
			}
		}
	}
		    
	else{
		if (supplyCount(estate, state) > 0){
			gainCard(estate, state, 0, currentPlayer);//Gain an estate
			state->supplyCount[estate]--;//Decrement Estates
			if (supplyCount(estate, state) == 0){
				isGameOver(state);
			}
		}
	} 
    
    return 0;
}

int great_hall_card(struct gameState *state, int currentPlayer, int handPos)
{
    //+1 Card
    drawCard(currentPlayer, state);
		
    //+1 Actions
    state->numActions++;
		
    //discard card from hand
    discardCard(handPos, currentPlayer, state, 0);
    return 0;
}

int minion_card(struct gameState *state, int currentPlayer, int handPos, int choice1, int choice2)
{
	int i;
	int j;
	
	//+1 action
	state->numActions++;
		
	//discard card from hand
	discardCard(handPos, currentPlayer, state, 0);
		
	if (choice1)		//+2 coins
	{
		state->coins = state->coins + 2;
	}
		
	else if (choice2)		//discard hand, redraw 4, other players with 5+ cards discard hand and draw 4
	{
		//discard hand
		while(numHandCards(state) > 0)
		{
			discardCard(handPos, currentPlayer, state, 0);
		}
			
		//draw 4
		for (i = 0; i < 4; i++)
		{
			drawCard(currentPlayer, state);
		}
			
		//other players discard hand and redraw if hand size > 4
		for (i = 0; i < state->numPlayers; i++)
		{
			if (i != currentPlayer)
			{
				if ( state->handCount[i] > 4 )
				{
					//discard hand
					while( state->handCount[i] > 0 )
					{
						discardCard(handPos, i, state, 0);
					}
						
					//draw 4
					for (j = 0; j < 4; j++)
					{
						drawCard(i, state);
					}
				}
			}
		}		
	}
    return 0;
}

int steward_card(struct gameState *state, int currentPlayer, int handPos, int choice1, int choice2, int choice3)
{
	if (choice1 == 1)
	{
		//+2 cards
		drawCard(currentPlayer, state);
		drawCard(currentPlayer, state);
	}
	else if (choice1 == 2)
	{
		//+2 coins
		state->coins = state->coins + 2;
	}
	else
	{
		//trash 2 cards in hand
		discardCard(choice2, currentPlayer, state, 1);
		discardCard(choice3, currentPlayer, state, 1);
	}
		
	//discard card from hand
	discardCard(handPos, currentPlayer, state, 0);
	return 0;
}

int tribute_card(struct gameState *state, int currentPlayer, int nextPlayer, int tributeRevealedCards[])
{
	int i;
	
	if ((state->discardCount[nextPlayer] + state->deckCount[nextPlayer]) <= 1){
		if (state->deckCount[nextPlayer] > 0){
			tributeRevealedCards[0] = state->deck[nextPlayer][state->deckCount[nextPlayer]-1];
			state->deckCount[nextPlayer]--;
		}
		else if (state->discardCount[nextPlayer] > 0){
			tributeRevealedCards[0] = state->discard[nextPlayer][state->discardCount[nextPlayer]-1];
			state->discardCount[nextPlayer]--;
		}
		else{
			//No Card to Reveal
			if (DEBUG){
				printf("No cards to reveal\n");
			}
		}
	}
    
	else{
		if (state->deckCount[nextPlayer] == 0){
			for (i = 0; i < state->discardCount[nextPlayer]; i++){
				state->deck[nextPlayer][i] = state->discard[nextPlayer][i];//Move to deck
				state->deckCount[nextPlayer]++;
				state->discard[nextPlayer][i] = -1;
				state->discardCount[nextPlayer]--;
			}
		    
			shuffle(nextPlayer,state);//Shuffle the deck
		} 
		tributeRevealedCards[0] = state->deck[nextPlayer][state->deckCount[nextPlayer]-1];
		state->deck[nextPlayer][state->deckCount[nextPlayer]--] = -1;
		state->deckCount[nextPlayer]--;
		tributeRevealedCards[1] = state->deck[nextPlayer][state->deckCount[nextPlayer]-1];
		state->deck[nextPlayer][state->deckCount[nextPlayer]--] = -1;
		state->deckCount[nextPlayer]--;
	}    
	       
	if (tributeRevealedCards[0] == tributeRevealedCards[1]){//If we have a duplicate card, just drop one 
		state->playedCards[state->playedCardCount] = tributeRevealedCards[1];
		state->playedCardCount++;
		tributeRevealedCards[1] = -1;
	}

	for (i = 0; i <= 2; i ++){
		if (tributeRevealedCards[i] == copper || tributeRevealedCards[i] == silver || tributeRevealedCards[i] == gold){//Treasure cards
			state->coins += 2;
		}
	    
		else if (tributeRevealedCards[i] == estate || tributeRevealedCards[i] == duchy || tributeRevealedCards[i] == province || tributeRevealedCards[i] == gardens || tributeRevealedCards[i] == great_hall){//Victory Card Found
			drawCard(currentPlayer, state);
			drawCard(currentPlayer, state);
		}
		else{//Action Card
			state->numActions = state->numActions + 2;
		}
	}
    
	return 0;
	
	
}

int ambassador_card(struct gameState *state, int currentPlayer, int handPos, int choice1, int choice2, int choice3)
{
	int i;
	int j = 0;		//used to check if player has enough cards to discard

	if (choice2 > 2 || choice2 < 0)
	{
		return -1;				
	}

	if (choice1 == handPos)
	{
		return -1;
	}

	for (i = 0; i < state->handCount[currentPlayer]; i++)
	{
		if (i != handPos && i == state->hand[currentPlayer][choice1] && i != choice1)
		{
			j++;
		}
	}
	if (j < choice2)
	{
		return -1;				
	}

	if (DEBUG) 
		printf("Player %d reveals card number: %d\n", currentPlayer, state->hand[currentPlayer][choice1]);

	//increase supply count for choosen card by amount being discarded
	state->supplyCount[state->hand[currentPlayer][choice1]] += choice2;
		
	//each other player gains a copy of revealed card
	for (i = 0; i < state->numPlayers; i++)
	{
		if (i != currentPlayer)
		{
			gainCard(state->hand[currentPlayer][choice1], state, 0, i);
		}
	}

	//discard played card from hand
	discardCard(handPos, currentPlayer, state, 0);			

	//trash copies of cards returned to supply
	for (j = 0; j < choice2; j++)
	{
		for (i = 0; i < state->handCount[currentPlayer]; i++)
		{
			if (state->hand[currentPlayer][i] == state->hand[currentPlayer][choice1])
			{
				discardCard(i, currentPlayer, state, 1);
				break;
			}
		}
	}			

	return 0;
	
}

int cutpurse_card(struct gameState *state, int currentPlayer, int handPos)
{
	int i;
	int j;
	int k;
	
	updateCoins(currentPlayer, state, 2);
	for (i = 0; i < state->numPlayers; i++)
	{
		if (i != currentPlayer)
		{
			for (j = 0; j < state->handCount[i]; j++)
			{
				if (state->hand[i][j] == copper)
				{
					discardCard(j, i, state, 0);
					break;
				}
				if (j == state->handCount[i])
				{
					for (k = 0; k < state->handCount[i]; k++)
					{
						if (DEBUG)
							printf("Player %d reveals card number %d\n", i, state->hand[i][k]);
					}	
					break;
				}		
			}
					
		}
				
	}				

	//discard played card from hand
	discardCard(handPos, currentPlayer, state, 0);			

	return 0;
	
}

int embargo_card(struct gameState *state, int currentPlayer, int handPos, int choice1)
{
	//+2 Coins
	state->coins = state->coins + 2;
		
	//see if selected pile is in play
	if ( state->supplyCount[choice1] == -1 )
	{
		return -1;
	}
		
	//add embargo token to selected supply pile
	state->embargoTokens[choice1]++;
		
	//trash card
	discardCard(handPos, currentPlayer, state, 1);		
	return 0;
	
}
	
int	outpost_card (struct gameState *state, int currentPlayer, int handPos)
{
    //set outpost flag
    state->outpostPlayed++;
		
    //discard card
    discardCard(handPos, currentPlayer, state, 0);
    return 0;
	
}
		
int salvager_card (struct gameState *state, int currentPlayer, int handPos, int choice1)
{
	//+1 buy
	state->numBuys++;
			
	if (choice1)
	{
		//gain coins equal to trashed card
		state->coins = state->coins + getCost( handCard(choice1, state) );
		//trash card
		discardCard(choice1, currentPlayer, state, 1);	
	}
			
	//discard card
	discardCard(handPos, currentPlayer, state, 0);
	return 0;
	
}
			
int sea_hag_card (struct gameState *state, int currentPlayer)
{
	int i;
	
	for (i = 0; i < state->numPlayers; i++){
		if (i != currentPlayer){
			state->discard[i][state->discardCount[i]] = state->deck[i][state->deckCount[i]--];			    
			state->deckCount[i]--;
			state->discardCount[i]++;
			state->deck[i][state->deckCount[i]--] = curse;//Top card now a curse
		}
	}
	return 0;
	
}

int treasure_map_card(struct gameState *state, int currentPlayer, int handPos)
{
	int i;
	int index;
	
	//search hand for another treasure_map
	index = -1;
	for (i = 0; i < state->handCount[currentPlayer]; i++)
	{
		if (state->hand[currentPlayer][i] == treasure_map && i != handPos)
		{
			index = i;
			break;
		}
	}
	if (index > -1)
	{
		//trash both treasure cards
		discardCard(handPos, currentPlayer, state, 1);
		discardCard(index, currentPlayer, state, 1);

		//gain 4 Gold cards
		for (i = 0; i < 4; i++)
		{
			gainCard(gold, state, 1, currentPlayer);
		}
				
		//return success
		return 1;
	}
			
	//no second treasure_map found in hand
	return -1;
	
}

int cardEffect(int card, int choice1, int choice2, int choice3, struct gameState *state, int handPos, int *bonus)
{
  int currentPlayer = whoseTurn(state);
  int nextPlayer = currentPlayer + 1;

  int tributeRevealedCards[2] = {-1, -1};
  int temphand[MAX_HAND];// moved above the if statement
  if (nextPlayer > (state->numPlayers - 1)){
    nextPlayer = 0;
  }
  
	
  //uses switch to select card and perform actions
  switch( card ) 
    {
	case adventurer:
		adventurer_card(state, currentPlayer, temphand); 
			
    case council_room:
     	council_room_card(state, currentPlayer, handPos);
			
    case feast:
     	feast_card(state, currentPlayer, choice1, temphand);
			
    case gardens:
      	gardens_card();
			
    case mine:
      	mine_card(state, currentPlayer, choice1, choice2, handPos);
			
    case remodel:
      	remodel_card(state, currentPlayer, choice1, choice2, handPos);
		
    case smithy:
		smithy_card(state, currentPlayer, handPos);
      
    case village:
		 village_card(state, currentPlayer, handPos);
		
    case baron:
		baron_card(state, currentPlayer, handPos, choice1);
		
    case great_hall:
		great_hall_card(state, currentPlayer, handPos);
		
    case minion:
      	minion_card(state, currentPlayer, handPos, choice1, choice2);
		
    case steward:
		steward_card(state, currentPlayer, handPos, choice1, choice2, choice3);
		
    case tribute:
		tribute_card(state, currentPlayer, nextPlayer, tributeRevealedCards);
      
    case ambassador:
      	ambassador_card(state, currentPlayer, handPos, choice1, choice2, choice3);
		
    case cutpurse:
		cutpurse_card(state, currentPlayer, handPos);
		
    case embargo: 
		embargo_card(state, currentPlayer, handPos, choice1);
		
    case outpost:
		outpost_card(state, currentPlayer, handPos);
		
    case salvager:
		salvager_card(state, currentPlayer, handPos, choice1);
		
    case sea_hag:
		sea_hag_card(state, currentPlayer);
		
    case treasure_map:
		treasure_map_card(state, currentPlayer, handPos);
	}
	
	return -1;
}

int discardCard(int handPos, int currentPlayer, struct gameState *state, int trashFlag)
{
	
  //if card is not trashed, added to Played pile 
  if (trashFlag < 1)
    {
      //add card to played pile
      state->playedCards[state->playedCardCount] = state->hand[currentPlayer][handPos]; 
      state->playedCardCount++;
    }
	
  //set played card to -1
  state->hand[currentPlayer][handPos] = -1;
	
  //remove card from player's hand
  if ( handPos == (state->handCount[currentPlayer] - 1) ) 	//last card in hand array is played
    {
      //reduce number of cards in hand
      state->handCount[currentPlayer]--;
    }
  else if ( state->handCount[currentPlayer] == 1 ) //only one card in hand
    {
      //reduce number of cards in hand
      state->handCount[currentPlayer]--;
    }
  else 	
    {
      //replace discarded card with last card in hand
      state->hand[currentPlayer][handPos] = state->hand[currentPlayer][ (state->handCount[currentPlayer] - 1)];
      //set last card to -1
      state->hand[currentPlayer][state->handCount[currentPlayer] - 1] = -1;
      //reduce number of cards in hand
      state->handCount[currentPlayer]--;
    }
	
  return 0;
}

int gainCard(int supplyPos, struct gameState *state, int toFlag, int player)
{
  //Note: supplyPos is enum of choosen card
	
  //check if supply pile is empty (0) or card is not used in game (-1)
  if ( supplyCount(supplyPos, state) < 1 )
    {
      return -1;
    }
	
  //added card for [whoseTurn] current player:
  // toFlag = 0 : add to discard
  // toFlag = 1 : add to deck
  // toFlag = 2 : add to hand

  if (toFlag == 1)
    {
      state->deck[ player ][ state->deckCount[player] ] = supplyPos;
      state->deckCount[player]++;
    }
  else if (toFlag == 2)
    {
      state->hand[ player ][ state->handCount[player] ] = supplyPos;
      state->handCount[player]++;
    }
  else
    {
      state->discard[player][ state->discardCount[player] ] = supplyPos;
      state->discardCount[player]++;
    }
	
  //decrease number in supply pile
  state->supplyCount[supplyPos]--;
	 
  return 0;
}

int updateCoins(int player, struct gameState *state, int bonus)
{
  int i;
	
  //reset coin count
  state->coins = 0;

  //add coins for each Treasure card in player's hand
  for (i = 0; i < state->handCount[player]; i++)
    {
      if (state->hand[player][i] == copper)
	{
	  state->coins += 1;
	}
      else if (state->hand[player][i] == silver)
	{
	  state->coins += 2;
	}
      else if (state->hand[player][i] == gold)
	{
	  state->coins += 3;
	}	
    }	

  //add bonus
  state->coins += bonus;

  return 0;
}


//end of dominion.c

